package com.jxtc.enterprise.admin.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jxtc.enterprise.admin.vo.AdminCompanySettlementPageVO;
import com.jxtc.enterprise.admin.vo.AdminStoreSettlementPageVO;
import com.jxtc.enterprise.common.constants.CompanySettlementStatusEnum;
import com.jxtc.enterprise.common.constants.OrderPaymentStatus;
import com.jxtc.enterprise.common.entity.*;
import com.jxtc.enterprise.common.mapper.OrderMapper;
import com.jxtc.enterprise.common.mapper.StoreMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class AdminStoreSettleService {

    private final OrderMapper orderMapper;

    /**
     * 填充店铺结算记录vo的各个字段
     * @param storeSettlement
     * @return
     */
    public AdminStoreSettlementPageVO buildStoreSettlementPageVO(StoreSettlement storeSettlement) {
        AdminStoreSettlementPageVO vo = new AdminStoreSettlementPageVO();
        vo.setId(storeSettlement.getId());
        vo.setStoreName(storeSettlement.getStoreName());
        vo.setMonth(storeSettlement.getMonth());
        vo.setStartDate(storeSettlement.getStartDate());
        vo.setEndDate(storeSettlement.getEndDate());

        // 获取提示日期，如果表中存放的提示提前天数为null，则默认提前1天提示
        Integer noteDay = storeSettlement.getNoteDay() == null ? 1 : storeSettlement.getNoteDay();
        vo.setNoteDay(noteDay);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate targetDate = LocalDate.parse(storeSettlement.getEndDate(), formatter);
        LocalDate currentDate = LocalDate.now();
        // 计算当前日期到目标日期还剩多少天
        long remainingDays = ChronoUnit.DAYS.between(currentDate, targetDate);
        vo.setRemainingDays(remainingDays);

        Integer statusValue = storeSettlement.getStatus();
        vo.setStatusValue(statusValue);
        vo.setStatusName(CompanySettlementStatusEnum.getNameByValue(statusValue));
        vo.setBillUrl(storeSettlement.getBillUrl());
        return vo;
    }

    public Map<String, String> buildStoreNameWithId(Store store) {
        Map<String, String> storeNameWithIdMap = new HashMap<>(1);
        storeNameWithIdMap.put("storeId", store.getId());
        storeNameWithIdMap.put("storeName", store.getName());
        return storeNameWithIdMap;
    }


    public StoreSettlement buildStoreSettlement(String companyId, String month, String startDate, String endDate, Integer noteDay) {
        StoreSettlement storeSettlement = new StoreSettlement();
        storeSettlement.setMonth(month);
        storeSettlement.setStartDate(startDate);
        storeSettlement.setEndDate(endDate);
        storeSettlement.setNoteDay(noteDay);

        LambdaQueryWrapper<OrderPayment> orderQueryWrapper = new LambdaQueryWrapper<OrderPayment>()
                .eq(OrderPayment::getCompanyId, companyId)
                .eq(OrderPayment::getStatus, OrderPaymentStatus.COMPLETED.getValue())
                .between(OrderPayment::getDateFlag, startDate, endDate)
                .orderByDesc(OrderPayment::getCreateTime);

        List<OrderPayment> orderPayments = orderMapper.selectList(orderQueryWrapper);
        // 订单总份数，没一份订单中可能包含多项餐品（目前来看通常是 1 份）
        int totalOrderCount = orderPayments.size();
        int orderMoneyInFen = 0;

        List<String> orderIds = new ArrayList<>();
        for (OrderPayment orderPayment : orderPayments) {
            orderIds.add(orderPayment.getId());

            // 理论上 orderPayment.getTotalAmount() - orderPayment.getUserPaid() 应该等于 orderPayment.getDeductionPrice()
            // 但是实际上业务员在平台管理填写菜品 sale_price 时经常和 show_price 一起输入为 0
            // 此时 orderPayment.getDeductionPrice() 的值在数据库中也为 0
            // 所以使用 "订单金额 - 用户自费金额" 来代替 "用户使用余额支付" 的部分
            // "用户使用余额支付" 的部分才是需要向 HR 结算的金额
            orderMoneyInFen += orderPayment.getTotalAmount() - orderPayment.getUserPaid();
        }

        storeSettlement.setTotalOrderCount(totalOrderCount);
        storeSettlement.setOrderMoney(orderMoneyInFen);

        // 生成账单 excel 文件并上传到 oss 中，然后将路径回填到 bill_url 中
        String billUrl = "https://www.enterprise.qiyetuancan.com/";
//        String billUrl = buildExcelAndUploadFileToOSS(orderIds, orderPayments);
        storeSettlement.setBillUrl(billUrl);

        return storeSettlement;
    }
}
